<template>
  <div class="container">
    <h1 class="title flex">{{ route.query.title }}</h1>

    <div class="area" :style="areaStyle"></div>
    <div class="list flex flex-wrap">
      <div
        v-for="item in list"
        :key="item.id"
        class="item flex"
        :class="{ selected: item.selected }"
        ref="itemRef"
      >
        {{ item.id }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onBeforeUnmount, onMounted, computed } from 'vue'
import { useRoute } from 'vue-router'

// 数据管理
const itemRef = ref(null)
const route = useRoute()
document.title = route.query.title
let list = reactive([
  { id: 1, selected: false },
  { id: 2, selected: false },
  { id: 3, selected: false },
  { id: 4, selected: false },
  { id: 5, selected: false },
  { id: 6, selected: false },
  { id: 7, selected: false },
  { id: 8, selected: false },
  { id: 9, selected: false },
  { id: 10, selected: false },
])
const mouseStatus = reactive({
  mouseDown: false,
})
const areaInfo = reactive({
  startX: 0,
  startY: 0,
  width: 0,
  height: 0,
  top: 0,
  left: 0,
})
// 计算属性
const areaStyle = computed(() => {
  return (
    areaInfo.width && {
      width: areaInfo.width + 'px',
      height: areaInfo.height + 'px',
      top: areaInfo.top + 'px',
      left: areaInfo.left + 'px',
      position: 'fixed',
      zIndex: 10,
      opacity: 1,
    }
  )
})
// 生命周期
onMounted(() => {
  init()
  getItemPosition()
})
onBeforeUnmount(() => {
  window.removeEventListener('mousedown', onMouseDown)
  window.removeEventListener('mousemove', onMouseMove)
  window.removeEventListener('mouseup', onMouseUp)
})

// 方法
// 获取每个item的位置信息
const getItemPosition = () => {
  const itemDom = itemRef.value
  list = list.map((v, i) => {
    const { top, left, width, height } = itemDom[i].getBoundingClientRect()
    return { ...v, top, left, width, height }
  })
}

const init = () => {
  window.addEventListener('mousedown', onMouseDown)
  window.addEventListener('mousemove', onMouseMove)
  window.addEventListener('mouseup', onMouseUp)
}

const onMouseDown = (e) => {
  areaInfo.startX = e.clientX
  areaInfo.startY = e.clientY
  // 记录起始点位
  areaInfo.left = e.clientX
  areaInfo.top = e.clientY
  mouseStatus.mouseDown = true
  console.log('鼠标按下')
}
const onMouseMove = (e) => {
  if (!mouseStatus.mouseDown) return
  const { startX, startY, top, left, width, height } = areaInfo
  const { clientX, clientY } = e
  areaInfo.width = Math.abs(clientX - startX)
  areaInfo.height = Math.abs(clientY - startY)

  // if(clientY < startY) areaInfo.top = clientY
  // if(clientX < startX) areaInfo.left = clientX
  // if(clientY > startY && top < startY) areaInfo.top = startY
  // if(clientX > startX && left < startX) areaInfo.left = startX

  // top和left取start和client中更小的一位
  areaInfo.left = Math.min(startX, clientX)
  areaInfo.top = Math.min(startY, clientY)

  // 判定是否选中item盒子
  list.forEach((v, i) => {
    if (
      v.left > left &&
      v.left + v.width < left + width &&
      v.top > top &&
      v.top + v.height < top + height
    ) {
      v.selected = true
    } else {
      v.selected = false
    }
  })
}
const onMouseUp = (e) => {
  areaInfo.startX = 0
  areaInfo.startY = 0
  areaInfo.width = 0
  areaInfo.height = 0
  areaInfo.top = 0
  areaInfo.left = 0
  mouseStatus.mouseDown = false
}
</script>

<style lang="scss" scoped>
.container {
  width: 100vw;
  min-height: 100vh;
  overflow-y: auto;
  background: #eee;
  .title {
    height: 160px;
  }

  .area {
    width: 0;
    height: 0;
    opacity: 0;
    background: rgba(0, 140, 255, 0.3);
    border: 1px solid rgb(0, 140, 255);
  }

  .list {
    position: relative;
    width: 300px;
    margin: 100px auto;
    z-index: 1;
    .item {
      width: 50px;
      height: 50px;
      background: rgb(53, 154, 255);
      color: white;
      margin: 0 10px 10px 0;

      &.selected {
        background: rgb(5, 224, 104);
      }
    }
  }
}
</style>
